package com.richard.library.http.util;

import android.text.TextUtils;

import com.richard.library.http.exception.HttpException;

import org.apache.http.conn.ConnectTimeoutException;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Date;


/**
 * <pre>
 * Description : 网络请求工具类
 * Author : admin-richard
 * Date : 2022/8/26 16:04
 * Changelog:
 * Version            Date            Author              Detail
 * ----------------------------------------------------------------------
 * 1.0         2022/8/26 16:04     admin-richard         new file.
 * </pre>
 */
public final class Utils {

    public static String toString(Object obj) {
        return obj == null ? "" : String.valueOf(obj);
    }

    /**
     * 是否属于实体对象
     *
     * @param clazz 对象class
     */
    public static boolean isEntity(Class<?> clazz) {
        return !(clazz.isAssignableFrom(String.class)
                || clazz.isAssignableFrom(CharSequence.class)
                || clazz.isAssignableFrom(Integer.class)
                || clazz.isAssignableFrom(int.class)
                || clazz.isAssignableFrom(Long.class)
                || clazz.isAssignableFrom(long.class)
                || clazz.isAssignableFrom(Double.class)
                || clazz.isAssignableFrom(double.class)
                || clazz.isAssignableFrom(Float.class)
                || clazz.isAssignableFrom(float.class)
                || clazz.isAssignableFrom(Byte.class)
                || clazz.isAssignableFrom(byte.class)
                || clazz.isAssignableFrom(Short.class)
                || clazz.isAssignableFrom(short.class)
                || clazz.isAssignableFrom(Boolean.class)
                || clazz.isAssignableFrom(boolean.class)
                || clazz.isAssignableFrom(Date.class)
                || clazz.isAssignableFrom(Character.class)
                || clazz.isAssignableFrom(char.class));
    }


    /**
     * 是否属于网络请求超时异常(包含建立连接超时异常的验证)
     */
    public static boolean isTimeout(Throwable error) {
        return validateTimeout(error,true);
    }

    /**
     * 是否属于网络请求超时异常(不包含建立连接超时异常的验证)
     */
    public static boolean isSocketIOTimeout(Throwable error) {
        return validateTimeout(error,false);
    }

    /**
     * 验证异常是否属于网络请求超时
     */
    private static boolean validateTimeout(Throwable e,boolean isValidateConnectException) {
        if (e == null) {
            return false;
        }

        Class<?> clazz = e.getClass();
        boolean isTimeout = (isValidateConnectException && (clazz.isAssignableFrom(ConnectException.class) || clazz.isAssignableFrom(ConnectTimeoutException.class)))
                || clazz.isAssignableFrom(InterruptedIOException.class)
                || clazz.isAssignableFrom(SocketException.class)
                || clazz.isAssignableFrom(SocketTimeoutException.class)
                || clazz.isAssignableFrom(IOException.class);

        if(isTimeout){
            return true;
        }

        if (e instanceof HttpException th) {
            return validateTimeout(th.getOriginException(),isValidateConnectException);
        }

        return false;
    }

    /**
     * 是否属于json
     */
    public static boolean isJson(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        str = str.trim();
        if (str.startsWith("{") && str.endsWith("}")) {
            return true;
        }
        return str.startsWith("[") && str.endsWith("]");
    }

    /**
     * 是否属于xml
     */
    public static boolean isXml(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        str = str.trim();
        return str.startsWith("<") && str.endsWith(">");
    }


    /**
     * 保存文件
     *
     * @param inputStream 输入流
     * @param saveFile    保存文件
     */
    public static File saveFile(InputStream inputStream, File saveFile) throws IOException {
        try (FileOutputStream fileOutputStream = new FileOutputStream(saveFile); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
            //获取文件总长度
            //long totalLength = inputStream.available();
            byte[] buffer = new byte[1024];
            int len;

            while ((len = bufferedInputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, len);
            }
            fileOutputStream.flush();
            fileOutputStream.close();
            bufferedInputStream.close();
            inputStream.close();

            //回调成功
            return saveFile;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception ignored) {

            }
        }
    }

    /**
     * Return the nonnull object or default object.
     *
     * @param object        The object.
     * @param defaultObject The default object to use with the object is null.
     * @param <T>           The value type.
     * @return the nonnull object or default object
     */
    public static <T> T getOrDefault(final T object, final T defaultObject) {
        if (object == null) {
            return defaultObject;
        }
        return object;
    }


    /**
     * 获取字符串（若字符串为""或者null，则返回指定默认值，否则返回value）
     *
     * @param value        原值
     * @param defaultValue 默认值
     */
    public static String getValueOrDefault(final String value, final String defaultValue) {
        if (TextUtils.isEmpty(value)) {
            return defaultValue;
        }
        return value;
    }
}
